#include "user.h"
#include "command.h"
#include "taskQueue.h"
#include <string.h>
char *argv1="usrInfo";

char randomChar[] = {
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '/'
};
int generate_salt(char *salt,int len){
    salt[0]='$';   
    salt[1]='6';   
    salt[2]='$';   
    salt[len-1]='$';
    srand(time(NULL));
    for(int i=3;i<len-1;++i){
        int tmp=rand()%64;
        salt[i]=randomChar[tmp];
    }
    return 0;
} 

int userRegistration(usrInfo_t *pUsrInfo,MYSQL *mysql){
    int nameLen; 
    char usrName[16]={0};
    char argv2[32]={0};
    int len=INIT_SIZE;
    char salt[INIT_SIZE+1]={0};
    while(1){
        memset(usrName,0,sizeof(usrName));
        memset(argv2,0,sizeof(argv2));
        memset(salt,0,INIT_SIZE+1);
        recv(pUsrInfo->netFd,&nameLen,sizeof(int),MSG_WAITALL);
        recv(pUsrInfo->netFd,&usrName,nameLen,MSG_WAITALL);
        usrName[nameLen] = '\0'; // 手动添加字符串结束符
        sprintf(argv2,"usrName='%s'",usrName);
        MySQLSentence(SELECT,mysql,"id",argv1,argv2);
        MYSQL_RES *queryRes=NULL;
        queryRes=mysql_store_result(mysql);
        MYSQL_ROW row;
        if ((row = mysql_fetch_row(queryRes))) {
            // 用户名重复 
            commandType type=ERROR;
            send(pUsrInfo->netFd,&type,sizeof(ERROR),0);
            continue;
        }
        else{
            // 生成盐值发送
            generate_salt(salt,len);
            send(pUsrInfo->netFd,&len,sizeof(len),0); 
            send(pUsrInfo->netFd,&salt,len,0); 
            break;
        }
    }
    // 接收密文
    int enpwdLen;
    char enpwd[128]={0};
    recv(pUsrInfo->netFd,&enpwdLen,sizeof(int),MSG_WAITALL);
    recv(pUsrInfo->netFd,&enpwd,enpwdLen,MSG_WAITALL);
    // 写入数据库
    char *argv3="(fileName,fileSize,parentId,usrName,type,path,isDel)";
    char argv4[64]={0};
    sprintf(argv4,"('%s',%s,'%s','%s','%s','%s',%s","/","0","-1",usrName,"d","/","0)");
    MySQLSentence(INSERT,mysql,"fileInfo",argv3,argv4);
    MySQLSentence(SELECT,mysql,"id","fileInfo",argv2);
    MYSQL_RES *queryRes=NULL;
    queryRes=mysql_store_result(mysql);
    MYSQL_ROW row;
    row = mysql_fetch_row(queryRes);
    char *argv5="(id,usrName,salt,enpwd)";
    char argv6[64]={0};
    sprintf(argv6,"(%s,'%s','%s','%s')",row[0],usrName,salt,enpwd);
    MySQLSentence(INSERT,mysql,"usrInfo",argv5,argv6);
    memcpy(pUsrInfo->usrName,usrName,sizeof(usrName));

    commandType type=REG;
    send(pUsrInfo->netFd,&type,sizeof(int),0);
    return 0;
}

int userLogin(usrInfo_t *pUsrInfo,MYSQL *mysql){
    while(1){
        int nameLen; 
        char usrName[16]={0};
        commandType type;
        recv(pUsrInfo->netFd,&nameLen,sizeof(int),MSG_WAITALL);
        recv(pUsrInfo->netFd,&usrName,nameLen,MSG_WAITALL);
        // 查询和发送盐值
        char argv2[32]={0};
        sprintf(argv2,"usrName='%s'",usrName);
        MySQLSentence(SELECT,mysql,"salt,enpwd",argv1,argv2);
        MYSQL_RES *queryRes=NULL;
        queryRes=mysql_store_result(mysql);
        MYSQL_ROW row;
        row = mysql_fetch_row(queryRes);
        int len=INIT_SIZE;
        if(!row){
            // 用户名不存在

            len=0;
            send(pUsrInfo->netFd,&len,sizeof(len),0); 
            continue;
        }
        char salt[20]={0};
        strcpy(salt,row[0]);
        send(pUsrInfo->netFd,&len,sizeof(len),0); 
        send(pUsrInfo->netFd,row[0],len,0); 
        // 接收密文
        int enpwdLen;
        char enpwd[128]={0};
        recv(pUsrInfo->netFd,&enpwdLen,sizeof(int),MSG_WAITALL);
        recv(pUsrInfo->netFd,&enpwd,enpwdLen,MSG_WAITALL);
        if (strcmp(enpwd,row[1])!=0) {  
            // 密码错误
            type=ERROR;
            send(pUsrInfo->netFd,&type,sizeof(int),0);
            continue;
        }
        else{
            // 通过验证
            type=LOG;
            memcpy(pUsrInfo->usrName,usrName,sizeof(usrName));
            send(pUsrInfo->netFd,&type,sizeof(int),0);
        }
        return 0;
    }
}
int user(usrInfo_t *pUsrInfo,MYSQL *mysql){

    commandType type;
    recv(pUsrInfo->netFd,&type,sizeof(type),0);
    if(type==REG){
        userRegistration(pUsrInfo,mysql);
    }
    else if(type==LOG){
        userLogin(pUsrInfo,mysql);
    }
    return 0;
}


